package nl.cloudfarming.client.planning.tactical;


/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.util.Calendar;
import java.util.Date;
import junit.framework.Assert;
import nl.cloudfarming.client.model.CropProtection;
import nl.cloudfarming.client.model.CropProtectionTask;
import nl.cloudfarming.client.model.ProductionUnit;
import nl.cloudfarming.client.model.PartField;
import nl.cloudfarming.client.model.FieldPlan;
import nl.cloudfarming.client.model.Operation;
import nl.cloudfarming.client.model.Task;
import org.junit.Ignore;
import org.junit.Test;

/**
 * Test to test persistence
 * @author Gerben & Merijn
 */

public class PlanningTacticalServiceIT {

    TacticalPlanningService service = new TacticalPlanningService();
    @Test
    public void createFieldPlanForYearTest(){
        int before = service.findAllFieldPlans().size();
        
        FieldPlan fieldPlan = service.createFieldPlanForYear("2011", 2011);

        Assert.assertEquals(2011,fieldPlan.getPlanYear());               

        Assert.assertEquals(before + 1,service.findAllFieldPlans().size());
        boolean assertionDone = false;
        for (FieldPlan plan : service.findAllFieldPlans()){
            
            if(plan.getId() == fieldPlan.getId()){
                Assert.assertTrue(plan.getName().contains("2011"));
                assertionDone = true;
            }
        }
        Assert.assertTrue(assertionDone);
    }
    
    @Test
    public void createTaskTest(){
        int before = service.findAllTasks().size();
        
        Task.Builder taskBuilder  = new Task.Builder().setEndDate(new Date()).setStartDate(new Date());
        
        service.createTask(taskBuilder);
        
        Assert.assertEquals(before + 1,service.findAllTasks().size());
    }
    
    @Test
    public void createOperationTest(){
        int before = service.findAllOperations().size();
        
        Operation.Builder operationBuilder = new Operation.Builder().setName("naam");
        
        service.createOperation(operationBuilder);
        
        Assert.assertEquals(before + 1,service.findAllOperations().size());
        
       
    }
    
    @Test
    public void createProductionUnitTest(){
        int before = service.findAllProductionUnits().size();
        
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder().setName("naam");
        
        service.createProductionUnit(productionUnitBuilder);
        
        Assert.assertEquals(before + 1,service.findAllProductionUnits().size());
        
    }
    
    @Test
    public void createPartFieldTest(){
        int before = service.findAllPartFields().size();
        
        PartField.Builder fieldBuilder = new PartField.Builder();
        
        service.createPartField(fieldBuilder);
        
        Assert.assertEquals(before + 1,service.findAllPartFields().size());
    }
    
    @Test
    public void createCropProtectionTest(){
        
        
        int before = service.findAllCropProtections().size();
              
        CropProtection.Builder cropProtectionBuilder = new CropProtection.Builder().setName("naam").setLastUsage(new Date());
                
        CropProtection cropProtection= service.createCropProtection(cropProtectionBuilder);
        
        Assert.assertEquals(before + 1,service.findAllCropProtections().size());
        
        boolean isAsserted = false;
        for(CropProtection cp : service.findAllCropProtections()){
            if(cropProtection.getId() == cp.getId()){
                Assert.assertTrue(cp.getName().equals("naam"));
                isAsserted = true;
            }
        }
        Assert.assertTrue(isAsserted);
        
    }
    
    @Test
    public void createCropProtectionTaskTest(){
        
        
        int before = service.findAllCropProtectionTasks().size();
              
        CropProtectionTask.Builder cropProtectionBuilder = new CropProtectionTask.Builder().setQuantity(200D);
                
        CropProtectionTask cropProtectionTask= service.createCropProtectionTask(cropProtectionBuilder);
        
        Assert.assertEquals(before + 1,service.findAllCropProtectionTasks().size());
        
        boolean isAsserted = false;
        for(CropProtectionTask cpt : service.findAllCropProtectionTasks()){
            if(cropProtectionTask.getId() == cpt.getId()){
                Assert.assertTrue(cpt.getQuantity() == 200L);
                isAsserted = true;
            }
        }
        Assert.assertTrue(isAsserted);
        
    }
    
       
    @Test
    public void findTaskByProductionUnitTest(){
        //Setup
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder().setName("naam");
        ProductionUnit productionUnit = service.createProductionUnit(productionUnitBuilder);
        
        
        Operation.Builder operationBuilder = new Operation.Builder();
        operationBuilder.setProductionUnit(productionUnit);
        
        Operation operation = service.createOperation(operationBuilder);
        
        
        Task.Builder taskBuilder = new Task.Builder().setOperation(operation);
        Task task = service.createTask(taskBuilder);
        
        Assert.assertEquals(task, service.findTaskByProductionUnitId(productionUnit.getId()).get(0));
        
    }
    
    @Test
    public void findCropProtectionByNameAndLastUsageTest() {
        //setup
        CropProtection.Builder cropProtectionBuilder = new CropProtection.Builder();
        Date lastUsage = new Date();
        cropProtectionBuilder.setLastUsage(lastUsage).setName("name");
        CropProtection persistedCp = service.createCropProtection(cropProtectionBuilder);
        
        //Test
        CropProtection cropProtection = service.findCropProtectionByNameAndLastUsage("name", lastUsage);
        Assert.assertNotNull(cropProtection);
        Assert.assertEquals(persistedCp.getId(), cropProtection.getId());
        
        
        
    }
    
    @Test
    public void updateOperationTest(){
        Operation.Builder operationBuilder = new Operation.Builder().setName("name");
        Operation operation = service.createOperation(operationBuilder);
        operation.setName("changedName");
        service.updateOperation(operation);
        
        Assert.assertEquals("changedName", service.findOperationById(operation.getId()).getName());
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void updateNonPersistedOperationTest(){
        Operation.Builder operationBuilder = new Operation.Builder().setName("name");
        Operation operation = operationBuilder.build();
        operation.setName("changedName");
        service.updateOperation(operation);
        
        Assert.assertEquals("changedName", service.findOperationById(operation.getId()).getName());
    }
    
    @Test
    public void updateProductionUnitTest(){
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder();
        productionUnitBuilder.setName("name");
        ProductionUnit productionUnit = service.createProductionUnit(productionUnitBuilder);
        productionUnit.setName("changedName");
        service.updateProductionUnit(productionUnit);
        
        Assert.assertEquals("changedName", service.findProductionUnitById(productionUnit.getId()).getName());
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void updateNonPersistedProductionUnitTest(){
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder();
        productionUnitBuilder.setName("name");
        ProductionUnit productionUnit = productionUnitBuilder.build();
        productionUnit.setName("changedName");
        service.updateProductionUnit(productionUnit);
        
        Assert.assertEquals("changedName", service.findProductionUnitById(productionUnit.getId()).getName());
    }
    
    @Test
    public void updateTaskTest(){
        Task.Builder taskBuilder = new Task.Builder();
        taskBuilder.setStartDate(new Date());
        Task task = service.createTask(taskBuilder);
        task.setEndDate(new Date());
        service.updateTask(task);
        
        Assert.assertNotNull(service.findTaskById(task.getId()).getEndDate());
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void updateNonPersistedTaskTest(){
        Task.Builder taskBuilder = new Task.Builder();
        taskBuilder.setStartDate(new Date());
        Task task = taskBuilder.build();
        task.setEndDate(new Date());
        service.updateTask(task);
        
        Assert.assertNotNull(service.findTaskById(task.getId()).getEndDate());
    }
    
    @Test
    public void removeProductionUnitFromFieldPlanTest(){
        //Setup
        int before = service.findAllProductionUnits().size();
        FieldPlan fieldPlan = service.createFieldPlanForYear("", 2011);
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder().setName("naam").setFieldPlan(fieldPlan);
        ProductionUnit productionUnit = service.createProductionUnit(productionUnitBuilder);
        Assert.assertEquals(before + 1 , service.findAllProductionUnits().size());
        service.removeProductionUnitFromFieldPlan(productionUnit);
        Assert.assertEquals(before , service.findAllProductionUnits().size());
        
    }
    
    @Test
    public void findProductionUnitsByDateTest(){
        Date puDate = new Date();
        int before = service.findProductionUnitsByDate(puDate).size();
        
        //Create valid productionUnit
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(puDate.getTime() - 360000);
        Date startDate = calendar.getTime();
        calendar.setTimeInMillis(puDate.getTime() + 360000);
        Date endDate = calendar.getTime();
        
        ProductionUnit.Builder productionUnitBuilder = new ProductionUnit.Builder();
        productionUnitBuilder.setStartDate(startDate);
        productionUnitBuilder.setEndDate(endDate);
        
        service.createProductionUnit(productionUnitBuilder);
        
        Assert.assertEquals(before + 1, service.findProductionUnitsByDate(puDate).size()); 
        
        //Create invalid productionUnit
        calendar.setTimeInMillis(puDate.getTime() - 720000000);
        Date invalidStartDate = calendar.getTime();
        calendar.setTimeInMillis(puDate.getTime() - 360000000);
        Date invalidEndDate = calendar.getTime();
        
        Assert.assertTrue((invalidEndDate.getTime() - invalidStartDate.getTime()) == 360000000);
        
        Assert.assertTrue(invalidEndDate.getTime() < puDate.getTime() && invalidStartDate.getTime() < puDate.getTime());
        
        ProductionUnit.Builder invalidPuBuilder = new ProductionUnit.Builder();
        invalidPuBuilder.setStartDate(invalidStartDate);
        invalidPuBuilder.setEndDate(invalidEndDate);
        
        service.createProductionUnit(invalidPuBuilder);
        
        Assert.assertEquals(before + 1, service.findProductionUnitsByDate(puDate).size()); 
    }
    
    
    
    
}
